#ifndef __WIN32SOCKET_H__ 
#define __WIN32SOCKET_H__

typedef unsigned int * win32_socket;
typedef void *        win32_WSAEvent;

#define INVALID_ERROR_CODE        0x88888888

typedef struct win32_sockaddr {
    unsigned short sa_family;
    char    sa_data[14];
}win32_sockaddr;

#ifndef FD_SETSIZE
#define FD_SETSIZE      64
#endif

typedef struct win32_fd_set {
    unsigned int fd_count;
    win32_socket  fd_array[FD_SETSIZE];
} win32_fd_set;

typedef struct win32_timeval {
    long tv_sec;         /* seconds */
    long tv_usec;        /* and microseconds */
}win32_timeval;


#define WIN32_FD_CLR(fd, set) do { \
    unsigned int __i; \
    for (__i = 0; __i < ((win32_fd_set *)(set))->fd_count ; __i++) { \
        if (((win32_fd_set*)(set))->fd_array[__i] == fd) { \
            while (__i < ((win32_fd_set *)(set))->fd_count-1) { \
                ((win32_fd_set *)(set))->fd_array[__i] = \
                    ((win32_fd_set *)(set))->fd_array[__i+1]; \
                __i++; \
            } \
            ((win32_fd_set *)(set))->fd_count--; \
            break; \
        } \
    } \
} while(0)

#define WIN32_FD_SET(fd, set) do { \
    unsigned int __i; \
    for (__i = 0; __i < ((win32_fd_set *)(set))->fd_count; __i++) { \
        if (((win32_fd_set*)(set))->fd_array[__i] == (fd)) { \
            break; \
        } \
    } \
    if (__i == ((win32_fd_set *)(set))->fd_count) { \
        if (((win32_fd_set *)(set))->fd_count < FD_SETSIZE) { \
            ((win32_fd_set *)(set))->fd_array[__i] = (fd); \
            ((win32_fd_set *)(set))->fd_count++; \
        } \
    } \
} while(0)

#define WIN32_FD_ZERO(set) (((win32_fd_set *)(set))->fd_count=0)

extern int WIN32_FD_IS_SET(win32_socket so, win32_fd_set * set);
#define WIN32_FD_ISSET(fd, set) WIN32_FD_IS_SET((win32_socket)(fd), (win32_fd_set*)(set))

int WIN32_WSAStartup(void);
int WIN32_WSACleanup(void);

int WIN32_socket(int af,
                 int type,
                 int protocal,
                 win32_socket *pwin32_Socket);

int WIN32_connect(win32_socket s,
                  const struct win32_sockaddr *name,
                  int namelen);

int WIN32_bind(win32_socket s,
               const struct win32_sockaddr *name,
               int namelen);

int WIN32_listen(win32_socket s, int backlog);

int WIN32_accept(win32_socket s,
                 struct win32_sockaddr *addr,
                 int *addrlen,
                 win32_socket *pwin32_Socket);

int WIN32_send(win32_socket s,
               const char *buf,
               int len, int flags, int *outlen);

int WIN32_recv(win32_socket s, char *buf, int len, int flags, int *recvlen);

int WIN32_sendto(win32_socket s, 
                 const char *buf,
                 int len, int flags, 
                 const struct win32_sockaddr *to,
                 int tolen, int *sendLen);

int WIN32_recvfrom(win32_socket s,
                   char *buf, int len, int flags,
                   struct win32_sockaddr *from, int *fromlen,
                   int *recvLen);

int WIN32_getsockname(win32_socket s, struct win32_sockaddr *name, int *namelen);

int WIN32_getpeername(win32_socket s, struct win32_sockaddr *name, int *namelen);

int WIN32_select(int fds,
                 win32_fd_set *readfds,
                 win32_fd_set *writefds,
                 win32_fd_set *exceptfds,
                 win32_timeval *timeout,
                 int *number);

int WIN32_ioctlsocket(win32_socket s, long cmd, unsigned long *argp);

int WIN32_shutdown(win32_socket s, int how);

int WIN32_getsockopt(win32_socket s, int level, int optname, char *optval, int *optlen);

int WIN32_setsockopt(win32_socket s, int level, int optname, const char *optval, int optlen);

int WIN32_closesocket(win32_socket s);

int WIN32_WSAEventSelect(win32_socket s,
                         win32_WSAEvent hEventObject,
                         long lNetworkEvents);

unsigned int WIN32_inet_addr(const char *cp);

#endif
